home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagg_m.zip / MATH.SWG / 0052_Real Calculations.pas < prev    next >
Pascal/Delphi Source File  |  1994-01-27  |  3KB  |  79 lines

  1. {
  2. >How about using fixed point math to speed things up even more - not
  3. >everyone has a math coproccesor (either my routines suck, or REAL
  4. >calculations aren't fast, BTW I got most of my routines from Flights of
  5. >Fantasy).
  6.  
  7. > Well, its a combination, from my experience of flights of
  8. > fantasy, I'd say that it really isn't too speedy.  But then REAL
  9. > calculations are not notoriously quick either.  I think FOF is a Good
  10. > resource, it teaches 3d fundamentals well, and in general is pretty
  11. > nice, but the code is a little slow...  What I ended up doing is
  12. > reading through the book and writing from what they said. (for the most
  13. > part I skipped their code bits..)  I am not familiar with fixed point
  14. > math... I know what it is, but don't know how to implement it... Could
  15. > ya help a little?
  16.  
  17. Just (in this implementation) a longint, with the high 16 bits representing the
  18. integer part, and the low 16 representing the binary fraction (to 16 binary
  19. places). Basically a 32-bit binary number with the binary point fixed at the
  20. 16th position.
  21.  
  22. Adding and subtracting such numbers is just like working with straight
  23. longints. No problem. But when multiplying and dividing the number must be
  24. shifted so the binary point's still in the right place.
  25.  
  26. These are inline procedures, for speed, and only work on 386 or better,
  27. to save me headaches while coding this sucker.
  28. }
  29.  
  30. type
  31.   fixed = record
  32.   case byte of
  33.     0 : (f : word;
  34.          i : integer);
  35.     1 : (l : longint);
  36.   end;
  37.  
  38. {typecast parms to longint, result to fixed}
  39. function fixedDiv(d1, d2 : longint) : longint;
  40. inline(
  41.   $66/$59/               {pop ecx}
  42.   $58/                   {pop ax}
  43.   $5A/                   {pop dx}
  44.   $66/$0F/$BF/$D2/       {movsx edx,dx}
  45.   $66/$C1/$E0/$10/       {shl eax,16}
  46.   $66/$F7/$F9/           {idiv ecx}
  47.   $66/$0F/$A4/$C2/$10);  {shld edx,eax,16}   {no rounding}
  48.  
  49. {typecast parms to longint, result to fixed}
  50. function fixedMul(d1, d2 : longint) : longint;
  51. inline(
  52.   $66/$59/               {pop ecx}
  53.   $66/$58/               {pop eax}
  54.   $66/$F7/$E9/           {imul ecx}
  55.   $66/$C1/$E8/$10);      {shr eax,16}
  56.  
  57. function scaleFixed(i, m, d : longint) : longint;
  58. inline(  {mul, then div, no ovfl}
  59.   $66/$5B/               {pop ebx}
  60.   $66/$59/               {pop ecx}
  61.   $66/$58/               {pop eax}
  62.   $66/$F7/$E9/           {imul ecx}
  63.   $66/$F7/$FB/           {idiv ebx}
  64.   $66/$0F/$A4/$C2/$10);  {shld edx,eax,16}
  65.  
  66. var
  67.   a, b : fixed;
  68.  
  69. begin
  70.   a.l := $30000;
  71.   outputFixed(a.l + fixedDiv(a.l, $20000));
  72.   b.l := fixedMul(a.l, $48000);
  73.   outputFixed(b.l);
  74.   outputFixed(fixedDiv(b.l, $60000 + a.l));
  75.   outputFixed(scaleFixed($30000, $48000, $60000));
  76. end.
  77.  
  78. I'll let you figure out outputFixed for yourself.
  79.